package com.spatio.serving.basic.service.template.core.component.invoker;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.spatio.serving.basic.service.template.common.constant.HeaderConstant;
import com.spatio.serving.basic.service.template.common.invoke.req.MidUserLoginOrRegisterReq;
import com.spatio.serving.basic.service.template.common.invoke.req.MidUserSendEmailCodeReq;
import com.spatio.serving.common.lib.common.entity.ApiResponse;
import com.spatio.serving.common.lib.common.http.SpatioHttpClient;
import com.spatio.serving.common.lib.common.util.JsonUtil;
import com.spatio.serving.common.lib.common.util.LatencyWatch;
import com.spatio.serving.spring.boot.starter.core.context.SpatioLoginContext;
import com.spatio.serving.spring.boot.starter.prometheus.op.impl.HttpInvokePrometheusOp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * @Description
 * @Author GuoPengfei
 * @Date 2024/6/3 16:53
 */
@Component
@Slf4j
public class cMidUserInvoker {

    @Resource
    private SpatioHttpClient spatioHttpClient;

    @Value("${url.miduser.send.email.code}")
    private String urlMidUserSendEmailCode;

    @Value("${url.miduser.login.or.register}")
    private String urlMidUserLoginOrRegister;

//    @Value("${url.miduser.register}")
//    private String urlMidUserRegister;
//
//    @Value("${url.miduser.login}")
//    private String urlMidUserLogin;

    @Value("${switch.on.code.check:true}")
    private Boolean switchOnCodeCheck;

    private static final int TIME_OUT_MS = 3000;

    public ApiResponse sendEmailCode(String email, String uqId, String language) {
        MidUserSendEmailCodeReq req = MidUserSendEmailCodeReq.builder()
                .email(email)
                .bizType(1)     // 1:register 2:login
                .build();
        Map<String, String> map = new HashMap<>();
        map.put("appid", "calories");
        map.put("uq_id", uqId);
        // Define your headers here
        Map<String, String> headers = new HashMap<>();
        headers.put(HeaderConstant.X_SPATIO_LANGUAGE, language);

        String url = addParams(urlMidUserSendEmailCode, map);
        try {
            HttpInvokePrometheusOp.op().qpsTotal("OssInvoker_sendEmailCode");
            String param = JsonUtil.toJson(req);
            log.info("MidUserInvoker  sendEmailCode param:{}", param);
            long httpStart = System.currentTimeMillis();

            LatencyWatch watch = LatencyWatch.start();
            String responseStr = spatioHttpClient.postWithBody(url, param, headers, TIME_OUT_MS);
            log.info("MidUserInvoker sendEmailCode cost:{} result:{}", watch.cost(), responseStr);
            HttpInvokePrometheusOp.op().latency("OssInvoker_getCompleteUrl", (System.currentTimeMillis() - httpStart), TimeUnit.MILLISECONDS);
            HttpInvokePrometheusOp.op().qpsTotal("OssInvoker_getCompleteUrl");
            if (responseStr == null) {
                log.error("MidUserInvoker sendEmailCode responseStr is null url={}, http result body is null", url);
                return ApiResponse.failure(SpatioLoginContext.generateTraceId());
            }
            ApiResponse response = JsonUtil.fromJson(responseStr, ApiResponse.class);
            if (response.getCode() != 0) {
                log.error("MidUserInvoker  sendEmailCode response.getCode() is error url={}, code is error responseStr:{}", url, responseStr);
                return ApiResponse.failure(response.getCode(), response.getMsg(), SpatioLoginContext.generateTraceId());
            }
            return ApiResponse.success(SpatioLoginContext.generateTraceId());
        } catch (Exception e) {
            log.error("MidUserInvoker sendEmailCode error url={} exception", url, e);
            return ApiResponse.failure(SpatioLoginContext.generateTraceId());
        }
    }

    public ApiResponse loginOrRegister(String email, String code, String uqId, String language) {
        MidUserLoginOrRegisterReq req = MidUserLoginOrRegisterReq.builder()
                .account(email)
                .code(code)
                .validCode(switchOnCodeCheck)
                .area(language)
                .build();
        Map<String, String> map = new HashMap<>();
        map.put("appid", "calories");
        map.put("uq_id", uqId);
        String url = addParams(urlMidUserLoginOrRegister, map);
        try {
            HttpInvokePrometheusOp.op().qpsTotal("MidUserInvoker_register");
            String param = JsonUtil.toJson(req);
            log.info("MidUserInvoker register param:{}", param);
            long httpStart = System.currentTimeMillis();
            LatencyWatch watch = LatencyWatch.start();
            String responseStr = spatioHttpClient.postWithBody(url, param, null, TIME_OUT_MS);
            log.info("MidUserInvoker register cost:{} result:{}", watch.cost(), responseStr);
            HttpInvokePrometheusOp.op().latency("MidUserInvoker_register", (System.currentTimeMillis() - httpStart), TimeUnit.MILLISECONDS);
            HttpInvokePrometheusOp.op().qpsTotal("MidUserInvoker_register");
            if (responseStr == null) {
                log.error("MidUserInvoker register url={}, http result body is null", url);
                return null;
            }
            return JsonUtil.fromJson(responseStr, ApiResponse.class);

        } catch (Exception e) {
            log.error("MidUserInvoker register url={} email:{} exception", url, email, e);
            return null;
        }
    }

//    public ApiResponse register(String email, String code) {
//        MidUserRegisterReq req = MidUserRegisterReq.builder()
//                .email(email)
//                .code(code)
//                .validCode(true)
//                .build();
//        String url = addParams(urlMidUserRegister, Collections.singletonMap("appid", "cappy"));
//        try {
//            HttpInvokePrometheusOp.op().qpsTotal("MidUserInvoker_register");
//            String param = JsonUtil.toJson(req);
//            log.info("MidUserInvoker register param:{}", param);
//            long httpStart = System.currentTimeMillis();
//            LatencyWatch watch = LatencyWatch.start();
//            String responseStr = spatioHttpClient.postWithBody(url, param, null, TIME_OUT_MS);
//            log.info("MidUserInvoker register cost:{} result:{}", watch.cost(), responseStr);
//            HttpInvokePrometheusOp.op().latency("MidUserInvoker_register", (System.currentTimeMillis() - httpStart), TimeUnit.MILLISECONDS);
//            HttpInvokePrometheusOp.op().qpsTotal("MidUserInvoker_register");
//            if (responseStr == null) {
//                log.error("MidUserInvoker register url={}, http result body is null", url);
//                return null;
//            }
//            return JsonUtil.fromJson(responseStr, ApiResponse.class);
//
//        } catch (Exception e) {
//            log.error("MidUserInvoker register url={} email:{} exception", url, email, e);
//            return null;
//        }
//    }

    private static final ObjectMapper objectMapper = new ObjectMapper();


    public static String getToken(ApiResponse response) {
        Map<String, String> map = objectMapper.convertValue(response.getResult(), Map.class);
        if (CollectionUtils.isNotEmpty(map) && map.containsKey("cookie")) {
            String cookie = map.get("cookie");
            if (StringUtils.isNotEmpty(cookie) && StringUtils.startsWith(cookie, "JSESSIONID=")) {
                return cookie.substring(11);
            }
        }
        return "";
    }

    public static String getUserid(ApiResponse response) {
        Map<String, String> map = objectMapper.convertValue(response.getResult(), Map.class);
        if (CollectionUtils.isNotEmpty(map) && map.containsKey("userid")) {
            return map.get("userid");
        }
        return "";
    }

    public static String getLoginType(ApiResponse response) {
        Map<String, String> map = objectMapper.convertValue(response.getResult(), Map.class);
        if (CollectionUtils.isNotEmpty(map) && map.containsKey("login_type")) {
            return map.get("login_type");
        }
        return "";
    }

    private static String addParams(String url, Map<String, String> params) {
        if (params == null || params.isEmpty()) {
            return url;
        }
        StringBuilder sb = new StringBuilder(url);
        if (url.contains("?")) {
            sb.append("&");
        } else {
            sb.append("?");
        }
        for (Map.Entry<String, String> entry : params.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        return sb.substring(0, sb.length() - 1);

    }

//    public String login(String email, String code) {
//        MidUserRegisterReq req = MidUserRegisterReq.builder()
//                .email(email)
//                .code(code)
//                .validCode(true)
//                .build();
//        String url = addParams(urlMidUserLogin, Collections.singletonMap("appid", "cappy"));
//
//        try {
//            HttpInvokePrometheusOp.op().qpsTotal("MidUserInvoker_login");
//            String param = JsonUtil.toJson(req);
//            log.info("MidUserInvoker login param:{}", param);
//            long httpStart = System.currentTimeMillis();
//            LatencyWatch watch = LatencyWatch.start();
//            String responseStr = spatioHttpClient.postWithBody(url, param, null, TIME_OUT_MS);
//            log.info("MidUserInvoker login cost:{} result:{}", watch.cost(), responseStr);
//            HttpInvokePrometheusOp.op().latency("MidUserInvoker_login", (System.currentTimeMillis() - httpStart), TimeUnit.MILLISECONDS);
//            HttpInvokePrometheusOp.op().qpsTotal("MidUserInvoker_login");
//            if (responseStr == null) {
//                log.error("MidUserInvoker login url={}, http result body is null", url);
//                return "";
//            }
//            ApiResponse response = JsonUtil.fromJson(responseStr, ApiResponse.class);
//            if (response.getCode() != 0) {
//                log.error("MidUserInvoker  login url={}, code is error", url);
//                return "";
//            }
//            return getToken(response);
//        } catch (Exception e) {
//            log.error("MidUserInvoker login url={} email:{} exception", url, email, e);
//            return "";
//        }
//    }
}

